package ilvonen.ihstatistics;

import ilvonen.ihstatistics.models.ConstantData;
import ilvonen.ihstatistics.models.Game;
import ilvonen.ihstatistics.models.Player;
import ilvonen.ihstatistics.models.Roster;
import ilvonen.ihstatistics.repository.DBAdapter;
import ilvonen.ihstatistics.repository.DBDefaultRoster;
import ilvonen.ihstatistics.repository.DBGames;
import ilvonen.ihstatistics.repository.DBPlayers;
import ilvonen.ihstatistics.repository.DBRoles;
import ilvonen.ihstatistics.repository.DBRoster;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;



import android.app.Activity;
import android.app.Application;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnClickListener;
import android.view.View.OnDragListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class RosterActivity extends Activity {
	
	private final Context context = this;
	/*
	 * Database classes needed for the db functions
	 * We need to fetch players and insert new game and roster for the game
	 */
	private DBAdapter _db = new DBAdapter(this);
	private DBPlayers _dbPlayers = new DBPlayers();
	private DBDefaultRoster _dbDefaultRoster = new DBDefaultRoster();
	private DBRoster _dbRoster = new DBRoster();
	private DBGames _dbGames = new DBGames();
	private DBRoles _dbRoles = new DBRoles();
	
	/*
	 * Some object lists needed in this activity
	 */
	private List<Player> _allPlayers = new ArrayList<Player>();
	private List<Roster> _newRoster = new ArrayList<Roster>();
	private List<Roster> _defaultRoster = new ArrayList<Roster>();
	
	/*
	 * These are needed for the LinearLayout playerList.
	 */
	private List<ConstantData> _roles = new ArrayList<ConstantData>();
	private List<HashMap<String, String>> fillMaps;
	private SimpleAdapter mListAdapter;
	
	/*
	 * For receiving intent extras
	 */
	private int extAccoId;
	private int extTeamId;
	private int extSeasonId;
	private int extSeasonTypeId;
	private int extLeagueId;
	private String extOpponentName;
	private String extGameDate;
	
	/*
	 * Generated id for dynamical textviews.
	 */
	private int fID;
	
	
	private List<TextView> _rosterTextViews = new ArrayList<TextView>();
	private LinearLayout playerList;
	/*
	 * These textviews shows the roster
	 */
	private TextView lw1;
	private TextView lw2;
	private TextView lw3;
	private TextView lw4;
	private TextView rw1;
	private TextView rw2;
	private TextView rw3;
	private TextView rw4;
	private TextView c1;
	private TextView c2;
	private TextView c3;
	private TextView c4;
	private TextView ld1;
	private TextView ld2;
	private TextView ld3;
	private TextView ld4;
	private TextView rd1;
	private TextView rd2;
	private TextView rd3;
	private TextView rd4;
	private TextView goalie1;
	private TextView goalie2;
	private TextView goalie3;
	
	
	/*
	 * The start button
	 */
	private Button btnStart; 
	
	private long gameid; 
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_roster);
		
		playerList = (LinearLayout)findViewById(R.id.playerList);
		
		lw1 = (TextView)findViewById(R.id.lw1);
		lw2 = (TextView)findViewById(R.id.lw2);
		lw3 = (TextView)findViewById(R.id.lw3);
		lw4 = (TextView)findViewById(R.id.lw4);
		rw1 = (TextView)findViewById(R.id.rw1);
		rw2 = (TextView)findViewById(R.id.rw2);
		rw3 = (TextView)findViewById(R.id.rw3);
		rw4 = (TextView)findViewById(R.id.rw4);
		c1 = (TextView)findViewById(R.id.c1);
		c2 = (TextView)findViewById(R.id.c2);
		c3 = (TextView)findViewById(R.id.c3);
		c4 = (TextView)findViewById(R.id.c4);
		ld1 = (TextView)findViewById(R.id.ld1);
		ld2 = (TextView)findViewById(R.id.ld2);
		ld3 = (TextView)findViewById(R.id.ld3);
		ld4 = (TextView)findViewById(R.id.ld4);
		rd1 = (TextView)findViewById(R.id.rd1);
		rd2 = (TextView)findViewById(R.id.rd2);
		rd3 = (TextView)findViewById(R.id.rd3);
		rd4 = (TextView)findViewById(R.id.rd4);
		goalie1 = (TextView)findViewById(R.id.goalie1);
		goalie2 = (TextView)findViewById(R.id.goalie2);
		goalie3 = (TextView)findViewById(R.id.goalie3);
		
		//add textviews to list for easier usage (must be in this order)
		//dont change this order
		_rosterTextViews.add(lw1);
		_rosterTextViews.add(c1);
		_rosterTextViews.add(rw1);
		_rosterTextViews.add(ld1);
		_rosterTextViews.add(rd1);
		
		//dont change this order
		_rosterTextViews.add(lw2);
		_rosterTextViews.add(c2);
		_rosterTextViews.add(rw2);
		_rosterTextViews.add(ld2);
		_rosterTextViews.add(rd2);
		
		//dont change this order
		_rosterTextViews.add(lw3);
		_rosterTextViews.add(c3);
		_rosterTextViews.add(rw3);
		_rosterTextViews.add(ld3);
		_rosterTextViews.add(rd3);
		
		//dont change this order
		_rosterTextViews.add(lw4);
		_rosterTextViews.add(c4);
		_rosterTextViews.add(rw4);
		_rosterTextViews.add(ld4);
		_rosterTextViews.add(rd4);
		
		//dont change this order
		_rosterTextViews.add(goalie1);
		_rosterTextViews.add(goalie2);
		_rosterTextViews.add(goalie3);
		
		btnStart = (Button)findViewById(R.id.btnStartGame);
		 
		for(TextView t : _rosterTextViews){
			//Set player positions as drop zones.
			t.setOnDragListener(new ChoiceDragListener());
			//Set player positions draggable.
			t.setOnLongClickListener(new ChoiceOnLongClickListener());
		}
		//get extras
		Bundle extras = getIntent().getExtras();
		if(extras != null){
			//Receive extras that NewGameSettings activity has sent here
			extAccoId = extras.getInt("accountId");
			extTeamId = extras.getInt("teamid");
			extSeasonId = extras.getInt("seasonid");
			extSeasonTypeId = extras.getInt("seasontypeid");
			extLeagueId = extras.getInt("leagueid");
			extOpponentName = extras.getString("opponent");
			extGameDate = extras.getString("date");
		}
		/*
		 * 1. Receive needed information from the database
		 */
		ReceiveInformation();
		SetRoster();
		PopulatePlayerListview();
		
		
		
		btnStart.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if(checkRoster()){
					//roster contains one full line and a goalie.
					
					//save new game to database
					saveNewGame();
					//save new roster to database
					saveRoster();
					//Start game activity
					Intent addGameStats = new Intent(context, AddGameStats.class);
					//put extras
					addGameStats.putExtra("gameid", gameid);
					addGameStats.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
					startActivity(addGameStats);
				}
			}

			
		});
	}
	/*
	 * Add new game to database and start new game
	 */
	
	private void saveNewGame() {
		// TODO Auto-generated method stub
		DBGames dbGames = new DBGames();
		_db.open();
		gameid = dbGames.insert(extOpponentName, extGameDate, extTeamId, extLeagueId, extSeasonId, extSeasonTypeId, 0, _db);
		_db.close();
		
	}
	/*
	 * Save newly created roster to database for the game
	 */
	private void saveRoster() {
		// TODO Auto-generated method stub
		
		DBRoster dbRoster = new DBRoster();
		_db.open();
		for(Roster r : _newRoster){
			dbRoster.insert((int)gameid, r.get_playerId(), r.get_lineId(), r.get_positionId(), r.get_sleeveNumber(), _db);
		}
		_db.close();
		
	}
	/*
	 * Check that roster includes atleast 1 full line and a goalie.
	 */
	private boolean checkRoster() {
		// TODO Auto-generated method stub
		boolean enoughPlayers = false;
		int fullLines = 0;
		int playersInLine = 0;
		int pos = 0;//1 == lw, 2 == c, 3 == rw, 4 == ld, 5 == rd, 6 == gk1, 7 == gk2, 8 == gk3;
		int line = 1;
		for(TextView t : _rosterTextViews){
			pos++;
			if(t.getTag() != null){
				Roster r = new Roster();
				r.set_lineId(line);
				r.set_playerId((Integer)t.getTag());
				r.set_positionId(pos);
				r.set_teamId(extTeamId);
				r.set_sleeveNumber(GetPlayerSleeveNumber(r.get_playerId()));
				_newRoster.add(r);
				playersInLine++;
				if(pos == 6 && fullLines > 0){
					//1.goalie
					enoughPlayers = true;
				}
			}
			if(line < 4 && pos == 5){
				if(playersInLine == 5){
					fullLines++;
				}
				playersInLine = 0;
				pos = 0;//check next line.
				line++;
			}
			
		}
		return enoughPlayers;
		
	}
	private int GetPlayerSleeveNumber(int playerId) {
		// TODO Auto-generated method stub
		for(Player p : _allPlayers){
			if(p.get_id() == playerId){
				return p.get_sleeveNumber();
			}
		}
		return 0;//should never reach here.
	}

	//Dragging starts when user has pressed an item for long time.
	private final class ChoiceOnLongClickListener implements OnLongClickListener{

		@Override
		public boolean onLongClick(View v) {
			// TODO Auto-generated method stub
			ClipData data = ClipData.newPlainText("", "");
			DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
			//start dragging the item touched
			v.startDrag(data, shadowBuilder, v, 0);
		    return true;
		}
		
	}
	
	
	
	/**
	 * DragListener will handle dragged views being dropped on the drop area
	 * - only the drop action will have processing added to it as we are not
	 * - amending the default behavior for other parts of the drag process
	 *
	 */
	private class ChoiceDragListener implements OnDragListener {
		@Override
		public boolean onDrag(View v, DragEvent event) {
			//get the view that item was dropped on
			
			
			switch (event.getAction()) {
			case DragEvent.ACTION_DRAG_STARTED:
				//no action necessary
				break;
			case DragEvent.ACTION_DRAG_ENTERED:
				//no action necessary
				
				break;
			case DragEvent.ACTION_DRAG_EXITED:        
				//no action necessary
				
				break;
			case DragEvent.ACTION_DROP:
				/*
				 * Here we can handle what happens when dragged item is dropped on some dropzone
				 */
				//some temp variables
				Object tmpTag;
				
				//get the view that was dragged
				View view = (View) event.getLocalState();
			
				//get the view that was dragged and dropped
				TextView source = (TextView) view;
				TextView target = (TextView) v;
				//check if source was in roster chart or in the list
				LinearLayout leftSideLayout = (LinearLayout)findViewById(R.id.activity_roster_vasen);
				LinearLayout rightSideLayout = (LinearLayout)findViewById(R.id.activity_roster_oikea);
				
				TextView draggedTextview = (TextView) leftSideLayout.findViewById(view.getId());
				TextView textViewInLayout = (TextView) rightSideLayout.findViewById(v.getId());//this should be != null if targetLayout belongs to activity_roster_oikea-layout
				
				if(draggedTextview != null){//source was from the roster chart
					
					
					//check if player was moved from the roster chart back to list
					if(textViewInLayout != null){
						tmpTag = source.getTag();
						TextView targetTextView = (TextView)rightSideLayout.findViewWithTag(tmpTag);
						if(targetTextView != null){
							targetTextView.setTag(tmpTag);
							targetTextView.setTextColor(Color.BLACK);
							targetTextView.setOnLongClickListener(new ChoiceOnLongClickListener());
							//player was moved from the chart to list. set source null.
							source.setText("");
							source.setTag(null);
						}
						
					}
					
					
					//check if target view is empty
					else if(target.getTag() != null){
						//target contains a player already
						//change info between these two textviews
						tmpTag = target.getTag();
						
						//1. check if source was empty
						if(source.getTag() != null){
							//source was empty
							target.setText(GetPlayerInfo((Integer)source.getTag()));
							target.setTag(source.getTag());
						}
						else{
							//source was not empty
							target.setText("");
							target.setTag(null);
						}
						//target was not empty so set source as target
						source.setText(GetPlayerInfo((Integer)tmpTag));
						source.setTag(tmpTag);
					}
					
					
					else{
						//target is empty
						//check if source was empty
						//must be checked in case both target and source are empty
						if(source.getTag() != null){
							target.setText(GetPlayerInfo((Integer)source.getTag()));
							target.setTag(source.getTag());
							source.setText("");
							source.setTag(null);
						}
					}
				}
				
				
				else{//source was from the list
					
					TextView targetedLayout = (TextView)rightSideLayout.findViewById(target.getId());
					//if targetedLayout != null then target in same layout than source. from list to list operation is not allowed.
					if(targetedLayout == null){
						//stop displaying the view in the list
						source.setTextColor(getResources().getColor(R.color.red));
						source.setOnLongClickListener(null);
						//check if target view is empty
						if(target.getTag() != null){
							//tmpTag has id that must be returned back to list
							tmpTag = target.getTag();
							LinearLayout leftSideLayout2 = (LinearLayout)findViewById(R.id.activity_roster_oikea);
							TextView convertBackToDraggable = (TextView)leftSideLayout2.findViewWithTag(tmpTag);
							if(convertBackToDraggable != null)//should be always != null when enter here
							{
								//convert list item back to normal
								convertBackToDraggable.setTextColor(Color.BLACK);
								convertBackToDraggable.setOnLongClickListener(new ChoiceOnLongClickListener());
								//insert new info to target
								target.setTag(source.getTag());
								target.setText(GetPlayerInfo((Integer)source.getTag()));
							}
						}
						else{
							//source from list, target empty
							target.setTag(source.getTag());
							target.setText(GetPlayerInfo((Integer)source.getTag()));
						}
					}
				}
				
				break;
			case DragEvent.ACTION_DRAG_ENDED:
				
				break;
			default:
				break;
			}
			return true;
		}
	} 
	/*
	 * 
	 */
	private void PopulatePlayerListview() {
		// TODO Auto-generated method stub
		//get all active players for the list
		int tmpNro = -1;
		String tmpName = "";
		String tmpRole = "";
		_db.open();
		_allPlayers = _dbPlayers.getAllPlayersByActivity(_db, 1);
		_roles = _dbRoles.getAllRoles(_db);
		_db.close();
		
		if(_allPlayers != null){
			
	        for(Player p : _allPlayers){
	  
	        	tmpNro = p.get_sleeveNumber();
	        	tmpName = p.get_lastname() + " " + p.get_firstname();
	        	for(ConstantData r : _roles){
	        		if(p.get_role() == r.get_id()){
	        			tmpRole = r.get_name();
	        		}
	        	}
	        	//layout parameters for the textview
	        	LayoutParams lparams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
	        	//create new textview to hold player info
	        	TextView tv=new TextView(this);
	        	//set parameters to the new textview
	        	tv.setLayoutParams(lparams);
	        	tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30);
	        	tv.setTextColor(Color.BLACK);
	        	/*
	        	 * add text to the textview. if else to adjust sleeve numbers properly
	        	 */
	        	if(tmpNro > 9){
	        		tv.setText("#" + tmpNro + "   " + tmpName + "     " + tmpRole);
	        	} else {
	        		tv.setText("#" + tmpNro + "    " + tmpName + "     " + tmpRole);
	        	}
	        	/*
	        	 * Set player id as a tag to every textview so we can identify those textviews in drag and drop
	        	 */
	        	tv.setId(findUnusedId());//this might be unnecessary
	        	tv.setTag(Integer.valueOf(p.get_id()));
	        	//add new textview to layout
	        	playerList.addView(tv);
	        	//set ontouchlistener for the textview for drag and drop functionality.
	        	
	        	if(PlayerIsInRoster(p.get_id())){
	        		//if player is in the default roster then player is not available in the list
	        		tv.setTextColor(getResources().getColor(R.color.red));
	        	}
	        	else{
	        		//only players that are not in the roster can be dragged and dropped from the list
	        		tv.setOnLongClickListener(new ChoiceOnLongClickListener());
	        		
	        	}
	        	//this allows us to drag&drop players from roster back to list.
	        	tv.setOnDragListener(new ChoiceDragListener());
	        }
		}
	}
	/*
	 * 
	 */
	private boolean PlayerIsInRoster(int i) {
		// TODO Auto-generated method stub
		for(Roster r : _defaultRoster){
			if(r.get_playerId() == i){
				return true;
			}
		}
		return false;
	}
	/*
	 * Set roster and show it in the textviews.
	 */
	private void SetRoster() {
		for(Roster r : _defaultRoster){
			int pid = r.get_playerId();
			int line = r.get_lineId();
			int pos = r.get_positionId();
			switch (line) {
				case 1:
					switch (pos) {
						case 1:
							//lw1
							lw1.setTag(Integer.valueOf(pid));
							lw1.setText(GetPlayerInfo(pid));
							break;
						case 2:
							//c1	
							c1.setTag(Integer.valueOf(pid));
							c1.setText(GetPlayerInfo(pid));
							break;
						case 3:
							//rw1
							rw1.setTag(Integer.valueOf(pid));
							rw1.setText(GetPlayerInfo(pid));
							break;
						case 4:
							//ld1
							ld1.setTag(Integer.valueOf(pid));
							ld1.setText(GetPlayerInfo(pid));
							break;
						case 5:
							//rd1
							rd1.setTag(Integer.valueOf(pid));
							rd1.setText(GetPlayerInfo(pid));
							break;
						case 6:
							goalie1.setTag(Integer.valueOf(pid));
							goalie1.setText(GetPlayerInfo(pid));
							break;
						case 7:
							goalie2.setTag(Integer.valueOf(pid));
							goalie2.setText(GetPlayerInfo(pid));
							break;
						case 8:
							goalie3.setTag(Integer.valueOf(pid));
							goalie3.setText(GetPlayerInfo(pid));
							break;
						default:
							break;
						}
					break;
				case 2:
					switch (pos) {
						case 1:
							lw2.setTag(Integer.valueOf(pid));
							lw2.setText(GetPlayerInfo(pid));
							break;
						case 2:
							c2.setTag(Integer.valueOf(pid));
							c2.setText(GetPlayerInfo(pid));			
							break;
						case 3:
							rw2.setTag(Integer.valueOf(pid));
							rw2.setText(GetPlayerInfo(pid));
							break;
						case 4:
							ld2.setTag(Integer.valueOf(pid));
							ld2.setText(GetPlayerInfo(pid));
							break;
						case 5:
							rd2.setTag(Integer.valueOf(pid));
							rd2.setText(GetPlayerInfo(pid));
							break;
						case 6:
							goalie1.setTag(Integer.valueOf(pid));
							goalie1.setText(GetPlayerInfo(pid));
							break;
						case 7:
							goalie2.setTag(Integer.valueOf(pid));
							goalie2.setText(GetPlayerInfo(pid));
							break;
						case 8:
							goalie3.setTag(Integer.valueOf(pid));
							goalie3.setText(GetPlayerInfo(pid));
							break;
						default:
							break;
					}
					break;
				case 3:
					switch (pos) {
						case 1:
							lw3.setTag(Integer.valueOf(pid));
							lw3.setText(GetPlayerInfo(pid));
							break;
						case 2:
							c3.setTag(Integer.valueOf(pid));
							c3.setText(GetPlayerInfo(pid));			
							break;
						case 3:
							rw3.setTag(Integer.valueOf(pid));
							rw3.setText(GetPlayerInfo(pid));
							break;
						case 4:
							ld3.setTag(Integer.valueOf(pid));
							ld3.setText(GetPlayerInfo(pid));
							break;
						case 5:
							rd3.setTag(Integer.valueOf(pid));
							rd3.setText(GetPlayerInfo(pid));
							break;
						case 6:
							goalie1.setTag(Integer.valueOf(pid));
							goalie1.setText(GetPlayerInfo(pid));
							break;
						case 7:
							goalie2.setTag(Integer.valueOf(pid));
							goalie2.setText(GetPlayerInfo(pid));
							break;
						case 8:
							goalie3.setTag(Integer.valueOf(pid));
							goalie3.setText(GetPlayerInfo(pid));
							break;
						default:
							break;
					}
					break;
				case 4:
					switch (pos) {
						case 1:
							lw4.setTag(Integer.valueOf(pid));
							lw4.setText(GetPlayerInfo(pid));
							break;
						case 2:
							c4.setTag(Integer.valueOf(pid));
							c4.setText(GetPlayerInfo(pid));			
							break;
						case 3:
							rw4.setTag(Integer.valueOf(pid));
							rw4.setText(GetPlayerInfo(pid));
							break;
						case 4:
							ld4.setTag(Integer.valueOf(pid));
							ld4.setText(GetPlayerInfo(pid));
							break;
						case 5:
							rd4.setTag(Integer.valueOf(pid));
							rd4.setText(GetPlayerInfo(pid));
							break;
						case 6:
							goalie1.setTag(Integer.valueOf(pid));
							goalie1.setText(GetPlayerInfo(pid));
							break;
						case 7:
							goalie2.setTag(Integer.valueOf(pid));
							goalie2.setText(GetPlayerInfo(pid));
							break;
						case 8:
							goalie3.setTag(Integer.valueOf(pid));
							goalie3.setText(GetPlayerInfo(pid));
							break;
						default:
							break;
					}
					break;
				default:
					switch (pos) {
						case 6:
							goalie1.setTag(Integer.valueOf(pid));
							goalie1.setText(GetPlayerInfo(pid));
							break;
						case 7:
							goalie2.setTag(Integer.valueOf(pid));
							goalie2.setText(GetPlayerInfo(pid));
							break;
						case 8:
							goalie3.setTag(Integer.valueOf(pid));
							goalie3.setText(GetPlayerInfo(pid));
							break;
						default:
							break;
					}
					break;
			}
		}
		
	}
	/*
	 * DONE. This function gives us the string for our textviews. eg. #9 Koivu
	 */
	private String GetPlayerInfo(int pid) {
		String info = "Error";
		for(Player p : _allPlayers){
			if(p.get_id() == pid){
				info = "#" + p.get_sleeveNumber() + " " + p.get_lastname(); 
				return info;
			}
		}
		return info;
	}
	/*
	 * Get players and default roster. Read from database.
	 */
	private void ReceiveInformation() {
		_db.open();
		_allPlayers = _dbPlayers.getAllPlayers(_db);
		_defaultRoster = _dbDefaultRoster.getDefaultRosterByTeamId(_db, extTeamId);
		_db.close();
		
	}
	/*
	 * Gives unique id for dynamically created textviews.
	 */
	public int findUnusedId() {
	    while( findViewById(++fID) != null );
	    return fID;
	}
}
